package handler

import (
	"blog_go/internal/model"
	"blog_go/internal/service"
	"blog_go/pkg/helper/resp"
	"net/http"

	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

type ArticleCommentHandler interface {
	QueryComment(ctx *gin.Context)
	QueryAllComment(ctx *gin.Context)
	AddComment(ctx *gin.Context)
	DelComment(ctx *gin.Context)
	ReviewComment(ctx *gin.Context)
	ReviewAllComment(ctx *gin.Context)
	LikeArticleComment(ctx *gin.Context)
	DisLikeArticleComment(ctx *gin.Context)
}

type articleCommentHandler struct {
	*Handler
	articleCommentService service.ArticleCommentService
}

func NewArticleCommentHandler(handler *Handler, articleCommentService service.ArticleCommentService) ArticleCommentHandler {
	return &articleCommentHandler{
		Handler:               handler,
		articleCommentService: articleCommentService,
	}
}

func (h *articleCommentHandler) QueryComment(ctx *gin.Context) {
	var params struct {
		ArticleId int `form:"articleId"`
		UserId    int `form:"userId"`
	}

	if err := ctx.ShouldBind(&params); err != nil {
		h.logger.Warn("QueryComment", zap.Any("error", err))
		resp.HandleError(ctx, http.StatusBadRequest, 1, err.Error(), nil)
		return
	}

	h.logger.Info("article attempted", zap.Any("articleId", params.ArticleId))

	data, err := h.articleCommentService.QueryComment(params.ArticleId, params.UserId)

	if err != nil {
		h.logger.Error("QueryComment failed", zap.Any("articleId", params.ArticleId), zap.Any("error", err))
		resp.HandleError(ctx, http.StatusInternalServerError, 1, err.Error(), nil)
		return
	}

	resp.HandleSuccess(ctx, data)
}

func (h *articleCommentHandler) QueryAllComment(ctx *gin.Context) {
	userId := GetUserIdFromCtx(ctx)
	if userId == 0 {
		resp.HandleError(ctx, http.StatusBadRequest, 1, "token错误", nil)
		return
	}

	userType := GetUserTypeFromCtx(ctx)
	if userType == -1 {
		resp.HandleError(ctx, http.StatusBadRequest, 1, "token错误", nil)
		return
	}

	h.logger.Info("QueryAllComment attempted", zap.Any("userId", userId), zap.Any("userType", userType))

	data, err := h.articleCommentService.QueryAllComment(userId, userType)

	if err != nil {
		h.logger.Error("QueryAllComment failed", zap.Any("userId", userId), zap.Any("userType", userType), zap.Any("error", err))
		resp.HandleError(ctx, http.StatusInternalServerError, 1, err.Error(), nil)
		return
	}

	resp.HandleSuccess(ctx, data)
}

// 新增评论
func (h *articleCommentHandler) AddComment(ctx *gin.Context) {
	var comment model.ArticleComment

	userId := GetUserIdFromCtx(ctx)
	if userId == 0 {
		resp.HandleError(ctx, http.StatusBadRequest, 1, "token错误", nil)
		return
	}

	if err := ctx.ShouldBind(&comment); err != nil {
		h.logger.Warn("AddComment", zap.Any("error", err))
		resp.HandleError(ctx, http.StatusBadRequest, 1, err.Error(), nil)
		return
	}

	h.logger.Info("article attempted", zap.Any("userId", comment.UserId))

	err := h.articleCommentService.AddComment(comment, userId)

	if err != nil {
		h.logger.Error("AddComment failed", zap.Any("userId", comment.UserId), zap.Any("error", err))
		resp.HandleError(ctx, http.StatusInternalServerError, 1, err.Error(), nil)
		return
	}

	resp.HandleSuccess(ctx, nil)
}

// 删除评论
func (h *articleCommentHandler) DelComment(ctx *gin.Context) {
	var params struct {
		CommentId int `json:"commentId"`
	}

	if err := ctx.ShouldBind(&params); err != nil {
		h.logger.Warn("DelComment", zap.Any("error", err))
		resp.HandleError(ctx, http.StatusBadRequest, 1, err.Error(), nil)
		return
	}

	userId := GetUserIdFromCtx(ctx)
	if userId == 0 {
		resp.HandleError(ctx, http.StatusBadRequest, 1, "token错误", nil)
		return
	}

	userType := GetUserTypeFromCtx(ctx)
	if userType == -1 {
		resp.HandleError(ctx, http.StatusBadRequest, 1, "token错误", nil)
		return
	}

	h.logger.Info("DelComment attempted", zap.Any("commentId", params.CommentId), zap.Any("userId", userId))

	err := h.articleCommentService.DelComment(params.CommentId, userId, userType)

	if err != nil {
		h.logger.Error("DelComment failed", zap.Any("commentId", params.CommentId), zap.Any("userId", userId), zap.Any("error", err))
		resp.HandleError(ctx, http.StatusInternalServerError, 1, err.Error(), nil)
		return
	}

	resp.HandleSuccess(ctx, nil)
}

// 审核评论
func (h *articleCommentHandler) ReviewComment(ctx *gin.Context) {
	var params struct {
		CommentIds []int `json:"commentIds"`
		Status     int   `json:"status"`
	}

	if err := ctx.ShouldBind(&params); err != nil {
		h.logger.Warn("ReviewComment", zap.Any("error", err))
		resp.HandleError(ctx, http.StatusBadRequest, 1, err.Error(), nil)
		return
	}

	h.logger.Info("ReviewComment attempted", zap.Any("params", params))

	err := h.articleCommentService.ReviewComment(params.CommentIds, params.Status)

	if err != nil {
		h.logger.Error("ReviewComment", zap.Any("params", params), zap.Any("error", err))
		resp.HandleError(ctx, http.StatusInternalServerError, 1, err.Error(), nil)
		return
	}

	resp.HandleSuccess(ctx, nil)
}

// 点赞、取消评论
func (h *articleCommentHandler) LikeArticleComment(ctx *gin.Context) {
	var params struct {
		CommentId int  `json:"commentId"`
		IsLike    bool `json:"islike"`
	}

	userId := GetUserIdFromCtx(ctx)
	if userId == 0 {
		resp.HandleError(ctx, http.StatusBadRequest, 1, "token错误", nil)
		return
	}

	if err := ctx.ShouldBind(&params); err != nil {
		h.logger.Warn("LikeArticle", zap.Any("error", err))
		resp.HandleError(ctx, http.StatusBadRequest, 1, err.Error(), nil)
		return
	}

	h.logger.Info("LikeArticle attempted", zap.Any("params", params))

	err := h.articleCommentService.LikeArticleComment(params.CommentId, userId, params.IsLike)

	if err != nil {
		h.logger.Error("LikeArticle failed", zap.Any("params", params), zap.Any("userId", userId), zap.Any("error", err))
		resp.HandleError(ctx, http.StatusInternalServerError, 1, err.Error(), nil)
		return
	}

	resp.HandleSuccess(ctx, nil)
}

// 反对或取消反对
func (h *articleCommentHandler) DisLikeArticleComment(ctx *gin.Context) {
	var params struct {
		CommentId int  `json:"commentId"`
		IsDisLike bool `json:"isdisLike"`
	}

	userId := GetUserIdFromCtx(ctx)
	if userId == 0 {
		resp.HandleError(ctx, http.StatusBadRequest, 1, "token错误", nil)
		return
	}

	if err := ctx.ShouldBind(&params); err != nil {
		h.logger.Warn("DisLikeArticle", zap.Any("error", err))
		resp.HandleError(ctx, http.StatusBadRequest, 1, err.Error(), nil)
		return
	}

	h.logger.Info("DisLikeArticle attempted", zap.Any("params", params))

	err := h.articleCommentService.DisLikeArticleComment(params.CommentId, userId, params.IsDisLike)

	if err != nil {
		h.logger.Error("DisLikeArticle failed", zap.Any("params", params), zap.Any("userId", userId), zap.Any("error", err))
		resp.HandleError(ctx, http.StatusInternalServerError, 1, err.Error(), nil)
		return
	}

	resp.HandleSuccess(ctx, nil)
}

// 一键审核评论
func (h *articleCommentHandler) ReviewAllComment(ctx *gin.Context) {
	err := h.articleCommentService.ReviewAllComment()
	if err != nil {
		h.logger.Error("ReveiewAllComment failed", zap.Any("error", err))
		resp.HandleError(ctx, http.StatusInternalServerError, 1, err.Error(), nil)
		return
	}

	resp.HandleSuccess(ctx, nil)
}
